﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
using System.Collections;

namespace EnumUtils.Extensions
{

  public static class FlagEnumExtensions
  {
//TODO: Add more extensions from the FlagEnumUtilities
//LEFT_OFF_HERE: Make as much of this library .NET 3.5 compatable as possible. In that vein, also consider putting the 4.0 only extensions in their own library.
      // RJM: This extension method doesn't work, why I don't know, so I have it commented out...
    public static IEnumerable<TEnum>
    AsEnumerable<TEnum>( this Enum flagEnum )
      where TEnum : IConvertible {
      Contract.Requires<ArgumentNullException>(!object.Equals(flagEnum, null));
      Contract.Requires<ArgumentException>(flagEnum is System.Enum);
      Contract.Requires<ArgumentException>(!flagEnum.GetType().IsAbstract, "This method is not contravariant. Please pass in a concrete enum type.");
      Contract.Requires<ArgumentException>(FlagEnumUtilities.DoesEnumHaveFlagsAttribute(flagEnum), ErrorMessageUtils.EnumNotAFlagsEnumMessage);

      return FlagEnumUtilities.ConvertFlagEnumToIEnumerable<TEnum>((dynamic)flagEnum);
    }




    /// <summary>
    /// Bit shifts the flag enum bit pattern leftward.
    /// </summary>
    /// 
    /// <param name="flagEnum">Flag enum instance to bit-shift on (is NOT modified)</param>
    /// 
    /// <param name="timesToShift">The number of times to shift the bit pattern.</param>
    /// 
    /// <returns></returns>
    /// 
    /// <exception cref="ArgumentException">
    /// Thrown when bitPattern is not a Flags enum.
    /// </exception>
    public static TEnum
    BitShiftLeft<TEnum>( this Enum flagEnum, int timesToShift )
      where TEnum : IConvertible {
      Contract.Requires<ArgumentNullException>(!object.Equals(flagEnum, null));

      return FlagEnumUtilities.BitShiftLeft<TEnum>((dynamic)flagEnum, timesToShift);
    } 

          

    /// <summary>
    /// Bit shifts the flag enum bit pattern rightward.
    /// </summary>
    /// 
    /// <param name="flagEnum"></param>
    /// 
    /// <param name="timesToShift">The number of times to shift the bit pattern.</param>
    /// 
    /// <returns></returns>
    public static TEnum
    BitShiftRight<TEnum>( this Enum flagEnum, int timesToShift )
      where TEnum : IConvertible {
      Contract.Requires<ArgumentNullException>(!object.Equals(flagEnum, null));
      
      return FlagEnumUtilities.BitShiftRight<TEnum>((dynamic)flagEnum, timesToShift);
    }




    #region Helper Methods
    #endregion
  }
}
